﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.IO;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
using Microsoft.Win32;
using Interpreter;

namespace LogoScriptIDE
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// 主窗口
    /// </summary>
    public partial class MainWindow : Window
    {
        #region Member Variables

        /// <summary>
        /// 各子窗口变量
        /// </summary>
        private CanvasWindow m_canvasWindow;
        private WatchesWindow m_watchesWindow;
        private StackWindow m_stackWindow;
        private ConsoleWindow m_consoleWindow;
        private DebuggerToolsWindow m_debuggerToolsWindow;
        private OptionWindow m_optionWindow;
        
        /// <summary>
        /// 小海龟变量
        /// </summary>
        private Turtle m_turtle;
        
        /// <summary>
        /// 解释器变量
        /// </summary>
        private Machine m_machine = new Machine();
        public Machine GetMachine()
        {
            return m_machine;
        }

        #endregion

        #region Initialization

        /// <summary>
        /// 窗口初始化
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 载入窗口
        /// </summary>
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //载入配置文件
            try
            {
                using (StreamReader sr = new StreamReader(autoConfigPath))
                    m_auto.Load(sr);
            }
            catch { }

            //创建窗口，创建系统函数，清空初始冗余信息，载入初始选项文件
            createWindows();
            createFunctions();
            m_editorWindow.KeyFunctions.Clear();
            foreach (var pair in m_functions)
                m_editorWindow.KeyFunctions.Add(pair.Key);
            LoadAutoConfig();
            m_optionWindow.LoadDefaultConfig(m_editorWindow.defaultConfig);
            m_optionWindow.LoadConfig(m_editorWindow.Configure);

            //计时器初始配置，启动
            m_timer = new System.Windows.Threading.DispatcherTimer(
                System.Windows.Threading.DispatcherPriority.Send);
            m_timer.Tick += new EventHandler(TimerTick);
            m_timer.Interval = new TimeSpan(0, 0, 0, 0, 10);
            m_timer.Start();

            //设置查找替换窗口父子关系
            findWindow.Owner = this;
            replaceWindow.Owner = this;
        }

        /// <summary>
        /// 创建窗口
        /// </summary>
        private void createWindows()
        {
            m_canvasWindow = new CanvasWindow();
            m_debuggerToolsWindow = new DebuggerToolsWindow();
            m_consoleWindow = m_debuggerToolsWindow.GetConsoleWindow();
            m_stackWindow = m_debuggerToolsWindow.GetStackWindow();
            m_watchesWindow = m_debuggerToolsWindow.GetWatchesWindow();
            
            m_optionWindow = new OptionWindow();
        }

        /// <summary>
        /// 创建系统函数
        /// </summary>
        private Dictionary<string, IFunction> m_functions
            = new Dictionary<string,IFunction>();
        private void createFunctions()
        {
            m_functions.Clear();
            m_functions.Add("PRINT", new FuncPrint(m_debuggerToolsWindow.GetConsoleWindow()));
            m_functions.Add("PRINTR", new FuncPRINTR(m_debuggerToolsWindow.GetConsoleWindow()));

            m_functions.Add("FD", new FuncFD(m_canvasWindow.Turtle));
            m_functions.Add("BK", new FuncBK(m_canvasWindow.Turtle));

            m_functions.Add("LT", new FuncLT(m_canvasWindow.Turtle));
            m_functions.Add("RT", new FuncRT(m_canvasWindow.Turtle));
            m_functions.Add("RESETA", new FuncRESETA(m_canvasWindow.Turtle));

            m_functions.Add("PU", new FuncPU(m_canvasWindow.Turtle));
            m_functions.Add("PD", new FuncPD(m_canvasWindow.Turtle));

            m_functions.Add("RESET", new FuncRESET(m_canvasWindow.Turtle));

            m_functions.Add("SETXY", new FuncSETXY(m_canvasWindow.Turtle));
            m_functions.Add("SETSIZE", new FuncSETSIZE(m_canvasWindow.Turtle));

            m_functions.Add("SETPC", new FuncSETPC(m_canvasWindow.Turtle));
            m_functions.Add("SETBK", new FuncSETBK(m_canvasWindow.Turtle));
            m_functions.Add("SETPW", new FuncSETPW(m_canvasWindow.Turtle));

            m_functions.Add("TEXT", new FuncTEXT(m_canvasWindow.Turtle));

            m_functions.Add("INPUT", new FuncINPUT(m_canvasWindow.Turtle,this));

            m_functions.Add("HIDE", new FuncHIDE(m_canvasWindow.Turtle));
            m_functions.Add("SHOW", new FuncSHOW(m_canvasWindow.Turtle));
            m_functions.Add("DELAY", new FuncDELAY());

            m_functions.Add("UPDATE", new FuncUPDATE(m_canvasWindow.Turtle));

            m_functions.Add("GETMOUSE", new FuncGETMOUSE(m_canvasWindow));

        }
        
        /// <summary>
        /// 向解释器中载入系统函数信息
        /// </summary>
        /// <param name="m">解释器</param>
        private void registerFunctions(Machine m)
        {
            foreach (var pair in m_functions)
            {
                m.SetGlobal(pair.Key, new Variable(pair.Value));
            }
        }

        #endregion

        #region Timer
        
        //解释器上一次状态
        private MachineStatus m_lastState = MachineStatus.MACHINE_STATUS_FINISHED;
        
        //解释器状态是否改变
        private bool m_stateChanged = true;
        
        //计时器变量
        private System.Windows.Threading.DispatcherTimer m_timer;

        //工具栏图标可用（不可用）的透明度设置
        private static readonly double EnableDefaultOpacity = 1;
        private static readonly double DisableDefaultOpacity = 0.3;
        
        /// <summary>
        /// 控制图标或菜单项是否在当前状态下可用
        /// </summary>
        /// <param name="b">工具栏按钮</param>
        /// <param name="m">菜单项</param>
        private void EnableTool(Button b,MenuItem m)
        {
            if (b != null)
            {
                b.IsEnabled = true;
                b.Opacity = EnableDefaultOpacity;
            }
            if (m != null) m.IsEnabled = true;
        }
        private void DisableTool(Button b, MenuItem m)
        {
            if (b != null)
            {
                b.IsEnabled = false;
                b.Opacity = DisableDefaultOpacity;
            }
            if (m != null) m.IsEnabled = false;
        }

        /// <summary>
        /// 计时器函数
        /// 进行轮询操作，每个周期观察其中函数是否有请求
        /// </summary>
        private void TimerTick(object sender, EventArgs e)
        {
            //解释器当前状态
            MachineStatus newState = m_machine.Status;

            //在解释器状态改变时，改变变量
            if (newState != m_lastState || m_stateChanged )
            {
                m_lastState = newState;
                m_stateChanged = false;

                //更新堆栈窗口和变量监视窗口
                m_debuggerToolsWindow.GetStackWindow().Update(m_machine);
                m_debuggerToolsWindow.GetWatchesWindow().m_Changed = 3;
                
                switch (newState)
                {
                    case MachineStatus.MACHINE_STATUS_RUNNING:
                        //改变工具栏工具的可用性
                        DisableTool(ui_toolNew, ui_mnuNew);
                        DisableTool(ui_toolOpen,ui_mnuOpen);
                        DisableTool(ui_toolSave,ui_mnuSave);
                        DisableTool(null, ui_mnuSaveAs);
                        DisableTool(ui_toolUndo, ui_mnuUndo);
                        DisableTool(ui_toolRedo, ui_mnuRedo);
                        DisableTool(ui_toolRun, ui_mnuRun);
                        DisableTool(ui_toolStepIn, ui_mnuStepin);
                        DisableTool(ui_toolStepOut, ui_mnuStepout);
                        DisableTool(ui_toolStepOver,ui_mnuStepover);
                        EnableTool(ui_toolPause,ui_mnuPause);
                        EnableTool(ui_toolStop,ui_mnuStop);
                        EnableTool(ui_toolExit,ui_mnuExit);

                        //对相关变量根据状态进行修改
                        m_editorWindow.PauseLine = -1;
                        m_editorWindow.ErrorLine = -1;
                        m_stackWindow.MouseDoubleClickFlag = false;
                        m_editorWindow.StackCallLine(-1);
                        
                        //编辑窗口加锁，不可更改
                        m_editorWindow.Locked = true;
                        break;
                    case MachineStatus.MACHINE_STATUS_PAUSED:
                        if (m_machine.CompileComplete)
                        {
                            DisableTool(ui_toolNew, ui_mnuNew);
                            DisableTool(ui_toolOpen, ui_mnuOpen);
                            DisableTool(ui_toolSave, ui_mnuSave);
                            DisableTool(null, ui_mnuSaveAs);
                            DisableTool(ui_toolUndo, ui_mnuUndo);
                            DisableTool(ui_toolRedo, ui_mnuRedo);
                            EnableTool(ui_toolRun, ui_mnuRun);
                            DisableTool(ui_toolPause,ui_mnuPause);
                            EnableTool(ui_toolStop,ui_mnuStop);
                            EnableTool(ui_toolStepIn, ui_mnuStepin);
                            EnableTool(ui_toolStepOut, ui_mnuStepout);
                            EnableTool(ui_toolStepOver,ui_mnuStepover);
                            EnableTool(ui_toolExit,ui_mnuExit);

                            m_editorWindow.PauseLine = m_machine.CurrentLine;
                            m_editorWindow.ui_editor.ScrollToLine(m_editorWindow.PauseLine);
                            m_editorWindow.Locked = true;
                        }
                        else
                        {
                            EnableTool(ui_toolNew, ui_mnuNew);
                            EnableTool(ui_toolOpen, ui_mnuOpen);
                            EnableTool(ui_toolSave, ui_mnuSave);
                            EnableTool(null, ui_mnuSaveAs);
                            EnableTool(ui_toolUndo, ui_mnuUndo);
                            EnableTool(ui_toolRedo, ui_mnuRedo);
                            EnableTool(ui_toolRun, ui_mnuRun);
                            DisableTool(ui_toolPause,ui_mnuPause);
                            DisableTool(ui_toolStop,ui_mnuStop);
                            EnableTool(ui_toolStepIn, ui_mnuStepin);
                            DisableTool(ui_toolStepOut, ui_mnuStepout);
                            EnableTool(ui_toolStepOver,ui_mnuStepover);
                            EnableTool(ui_toolExit,ui_mnuExit); 

                            m_editorWindow.StackCallLine(-1);
                            m_editorWindow.Locked = false;
                        }
                        break;
                    case MachineStatus.MACHINE_STATUS_FINISHED:
                        EnableTool(ui_toolNew, ui_mnuNew);
                        EnableTool(ui_toolOpen, ui_mnuOpen);
                        EnableTool(ui_toolSave, ui_mnuSave);
                        EnableTool(null, ui_mnuSaveAs);
                        EnableTool(ui_toolUndo, ui_mnuUndo);
                        EnableTool(ui_toolRedo, ui_mnuRedo);
                        EnableTool(ui_toolRun, ui_mnuRun);
                        DisableTool(ui_toolPause,ui_mnuPause);
                        DisableTool(ui_toolStop,ui_mnuStop);
                        EnableTool(ui_toolStepIn, ui_mnuStepin);
                        EnableTool(ui_toolStepOut, ui_mnuStepout);
                        DisableTool(ui_toolStepOver,ui_mnuStepover);
                        EnableTool(ui_toolExit,ui_mnuExit); 

                        m_editorWindow.PauseLine = -1;
                        m_editorWindow.ErrorLine = -1;
                        m_editorWindow.StackCallLine(-1);
                        m_editorWindow.Locked = false;
                        break;
                    case MachineStatus.MACHINE_STATUS_DEAD:
                        DisableTool(ui_toolNew, ui_mnuNew);
                        DisableTool(ui_toolOpen, ui_mnuOpen);
                        DisableTool(ui_toolSave, ui_mnuSave);
                        DisableTool(ui_toolRun, ui_mnuRun);
                        DisableTool(ui_toolPause,ui_mnuPause);
                        DisableTool(null, ui_mnuSaveAs);
                        DisableTool(ui_toolUndo, ui_mnuUndo);
                        DisableTool(ui_toolRedo, ui_mnuRedo);
                        EnableTool(ui_toolStop,ui_mnuStop);
                        DisableTool(ui_toolStepIn, ui_mnuStepin);
                        DisableTool(ui_toolStepOut, ui_mnuStepout);
                        DisableTool(ui_toolStepOver,ui_mnuStepover);
                        EnableTool(ui_toolExit,ui_mnuExit); 

                        string str = "Runtime Error: " + m_machine.LastErrorMessage + "\n";
                        m_consoleWindow.Write(str);
                        m_debuggerToolsWindow.Show();
                        m_debuggerToolsWindow.SwitchToTab(DebuggerToolsWindow.TabConsoleWindow);
                        m_editorWindow.ErrorLine = m_machine.CurrentLine;
                        m_editorWindow.ui_editor.ScrollToLine(m_editorWindow.ErrorLine);
                        m_editorWindow.Locked = true;
                        break;
                    default:
                        throw new Exception("Unexpected machine status detected.");
                }
            }

            //变量监视窗口改变，重新根据解释器进行更新
            if (m_watchesWindow.m_Changed > 0)
            {
                m_watchesWindow.m_Changed = 0;
                m_watchesWindow.Update(m_machine);
            }

            //选项窗口有新配置，将配置送入编辑窗口
            if (m_optionWindow.updateflag == true)
            {
                m_editorWindow.Configure = m_optionWindow.myconfig;
                m_editorWindow.UpdateConfig();
                m_optionWindow.updateflag = false;
            }
              
            //检测窗口可见性，控制菜单项前面的对勾
            ui_mnuViewCanvas.IsChecked = m_canvasWindow.IsVisible;
            ui_mnuViewDebuggerTools.IsChecked = m_debuggerToolsWindow.IsVisible;

            //如果编辑窗口锁住，相关功能失灵
            if (m_editorWindow.Locked)
            {
                ui_mnuCut.IsEnabled = false;
                ui_mnuPaste.IsEnabled = false;
                ui_mnuReplace.IsEnabled = false;
                ui_mnuComment.IsEnabled = false;
                ui_mnuUncomment.IsEnabled = false;
                replaceWindow.IsEnabled = false;
            }
            else
            {
                ui_mnuCut.IsEnabled = true;
                ui_mnuPaste.IsEnabled = true;
                ui_mnuReplace.IsEnabled = true;
                ui_mnuComment.IsEnabled = true;
                ui_mnuUncomment.IsEnabled = true;
                replaceWindow.IsEnabled = true;
            }
            m_canvasWindow.OnEditorIsReadOnlyChanged(m_editorWindow.Locked);

            //根据撤销堆栈的状态及编辑窗口锁的状态判断是否可以撤销及相关功能的可用性
            if (!m_editorWindow.ui_editor.CanUndo)
            {
                DisableTool(ui_toolUndo, ui_mnuUndo);
            }
            else
            {
                if (!m_editorWindow.Locked)
                    EnableTool(ui_toolUndo, ui_mnuUndo);
            }
            if (!m_editorWindow.ui_editor.CanRedo)
            {
                DisableTool(ui_toolRedo, ui_mnuRedo);
            }
            else
            {
                if (!m_editorWindow.Locked)
                    EnableTool(ui_toolRedo, ui_mnuRedo);
            }

            //当堆栈调用窗口有双击跳转请求时进行跳转
            if (m_machine.Status == MachineStatus.MACHINE_STATUS_PAUSED && m_stackWindow.MouseDoubleClickFlag == true)
            {
                m_editorWindow.ui_editor.ScrollToLine(m_stackWindow.doubleClickLine);
                m_editorWindow.StackCallLine(m_stackWindow.doubleClickLine);
                m_stackWindow.MouseDoubleClickFlag = false;
            }
        }
        #endregion

        #region File Commands

        //快捷键命令绑定
        public static RoutedCommand CommandOpen = new RoutedCommand();
        public static RoutedCommand CommandSave = new RoutedCommand();
        public static RoutedCommand CommandNew = new RoutedCommand();
        public static RoutedCommand CommandUndo = new RoutedCommand();
        public static RoutedCommand CommandRedo = new RoutedCommand();
        public static RoutedCommand CommandFind = new RoutedCommand();
        public static RoutedCommand CommandReplace = new RoutedCommand();

        /// <summary>
        /// 文件菜单下的点击事件
        /// </summary>
        private void mnuNew_Click(object sender, RoutedEventArgs e)
        {
            m_editorWindow.New();
        }

        private void mnuOpen_Click(object sender, RoutedEventArgs e)
        {
            m_editorWindow.Open();
        }

        private void mnuSave_Click(object sender, RoutedEventArgs e)
        {
            m_editorWindow.Save();
        }

        private void mnuSaveAs_Click(object sender, RoutedEventArgs e)
        {
            m_editorWindow.SaveAs();
        }

        private void mnuOption_Click(object sender, RoutedEventArgs e)
        {
            m_optionWindow.Show();
            //载入编辑窗口当前的配置
            m_optionWindow.LoadConfig(m_editorWindow.Configure);
        }

        private void ui_mnuSaveCanvas_Click(object sender, RoutedEventArgs e)
        {
            m_canvasWindow.Save();
        }

        private void ui_mnuSaveConsole_Click(object sender, RoutedEventArgs e)
        {
            m_consoleWindow.Save();
        }

        #endregion

        #region Edit Commands

        /// <summary>
        /// 编辑菜单下的点击事件
        /// </summary>
        private void mnuUndo_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (m_editorWindow.IsVisible)
                    m_editorWindow.Undo();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void mnuRedo_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (m_editorWindow.IsVisible)
                    m_editorWindow.Redo();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void mnuCut_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (m_editorWindow.IsVisible)
                    m_editorWindow.Cut();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void mnuCopy_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (m_editorWindow.IsVisible)
                    m_editorWindow.Copy();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void mnvPaste_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (m_editorWindow.IsVisible)
                    m_editorWindow.Paste();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void ui_mnuComment_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (m_editorWindow.IsVisible)
                    m_editorWindow.Comment();
            }
            catch (Exception) { }
        }

        private void ui_mnuUncomment_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (m_editorWindow.IsVisible)
                    m_editorWindow.Uncomment();
            }
            catch (Exception) { }
        }

        #region Find

        private FindWindow findWindow = new FindWindow();
        private void ui_mnuFind_Click(object sender, RoutedEventArgs e)
        {
            findWindow.Show();
        }

        public void FindNext(string text, bool caseSensitive)
        {
            m_editorWindow.FindNext(text, caseSensitive);
        }

        public void FindPrevious(string text, bool caseSensitive)
        {
            m_editorWindow.FindPrevious(text, caseSensitive);
        }

        #endregion

        #region Replace

        private ReplaceWindow replaceWindow = new ReplaceWindow();
        private void ui_mnuReplace_Click(object sender, RoutedEventArgs e)
        {
            replaceWindow.Show();
        }

        public void Replace(string text, string replace, bool caseSensitive)
        {
            m_editorWindow.Replace(text, replace, caseSensitive);
        }

        public void ReplaceAll(string text, string replace, bool caseSensitive)
        {
            m_editorWindow.ReplaceAll(text, replace, caseSensitive);
        }

        #endregion

        #endregion

        #region Run & Debug Commands

        /// <summary>
        /// 对编辑窗口中的代码进行编译，并返回编译错误信息
        /// </summary>
        private string Compile(Machine m)
        {
            try
            {
                m.Compile(new StringStream(m_editorWindow.Code));
            }
            catch (CompileException e)
            {
                string str = "Line " + e.Line.ToString() + ": " + e.Description;
                //告知错误行
                m_editorWindow.ErrorLine = e.Line;
                return str;
            }
            return "";
        }

        /// <summary>
        /// 对编辑窗口中的代码进行语法检查
        /// </summary>
        private void ui_mnuCheckSyntax_Click(object sender, RoutedEventArgs e)
        {
            string errorMessage = Compile(new Machine());
            if (errorMessage != "")
                m_consoleWindow.Write("Syntax Check Failed: " + errorMessage + "\n");
            else
                m_consoleWindow.Write("Syntax Check Passed.\n");
            //调试工具选项卡切换到输出窗口
            m_debuggerToolsWindow.Show();
            m_debuggerToolsWindow.SwitchToTab(DebuggerToolsWindow.TabConsoleWindow);
        }

        /// <summary>
        /// 收集断点信息给解释器
        /// </summary>
        private void SyncBreakPoints()
        {
            var machineBreakpointDict = m_machine.GetBreakpointList();
            List<int> machineBreakpointList = new List<int>();
            foreach (var breakpoint in machineBreakpointDict)
                machineBreakpointList.Add(breakpoint.Key);
            foreach (var breakpoint in machineBreakpointList)
                m_machine.RemoveBreakpoint(breakpoint);

            var breakpoints = m_editorWindow.BreakPoints;
            foreach (var breakpoint in breakpoints)
                m_machine.AddBreakpoint(breakpoint, true);

            HashSet<int> newBreakpoints = new HashSet<int>();
            var addedBreakpoints = m_machine.GetBreakpointList();
            foreach (var breakpoint in addedBreakpoints)
                newBreakpoints.Add(breakpoint.Key);
            m_editorWindow.BreakPoints = newBreakpoints;
        }

        /// <summary>
        /// 准备执行前的检查工作
        /// </summary>
        /// <returns>是否可执行</returns>
        private bool PrepareForExecution()
        {
            if (m_machine != null &&
                m_machine.Status == MachineStatus.MACHINE_STATUS_RUNNING)
                m_machine.Pause();
            m_machine = new Machine();
            registerFunctions(m_machine);

            string errorMessage = Compile(m_machine);
            if (errorMessage != "")
            {
                m_consoleWindow.Write("Compile Failed: " + errorMessage + "\n");
                m_consoleWindow.Write("Execution Aborted.\n");
                m_debuggerToolsWindow.Show();
                m_debuggerToolsWindow.SwitchToTab(DebuggerToolsWindow.TabConsoleWindow);
                return false;
            }
            else
            {
                m_consoleWindow.Write("Compile Successfully.\n");
            }
            //重置海龟
            m_canvasWindow.Turtle.ResetCanvas(640, 480);
            m_canvasWindow.Turtle.ResetStatus();
            m_canvasWindow.Turtle.Update(Turtle.UpdateMode.UPDATE_AUTO);

            return true;
        }
        
        /// <summary>
        /// 如果检查通过，送入解释器进行执行操作。
        /// </summary>
        private void CompileAndExecute()
        {
            if (!PrepareForExecution()) return;
            SyncBreakPoints();
            m_machine.Execute();
            m_stateChanged = true;
        }
        
        /// <summary>
        /// 停止按钮动作
        /// </summary>
        private void mnuStop_Click(object sender, RoutedEventArgs e)
        {
            m_stateChanged = true;
            if (m_machine.Status == MachineStatus.MACHINE_STATUS_RUNNING)
                m_machine.Pause();
            m_machine = new Machine();
            m_stateChanged = true;
            m_editorWindow.ErrorLine = -1;
            m_editorWindow.PauseLine = -1;
        }
        
        /// <summary>
        /// 运行按钮动作
        /// </summary>
        private void mnuRun_Click(object sender, RoutedEventArgs e)
        {
            //如果编辑窗口中代码有改变则返回，不继续执行
            if (!m_editorWindow.CheckModifiedCode(false) ||
                m_editorWindow.Modified)
                return;

            //如果是暂停后重新执行，重新收集断点信息，并执行。
            if (m_machine.Status == MachineStatus.MACHINE_STATUS_PAUSED &&
                m_machine.CompileComplete == true)
            {
                SyncBreakPoints();
                m_machine.Execute();
            }
            else
                CompileAndExecute();
            m_stateChanged = true;
        }
        
        /// <summary>
        /// 暂停按钮动作
        /// </summary>
        private void mnuPause_Click(object sender, RoutedEventArgs e)
        {
            m_machine.Pause();
        }
        
        /// <summary>
        /// 调试前的检查
        /// </summary>
        /// <returns>是否可以开始调试</returns>
        private bool PrepareForDebug()
        {
            if (!m_editorWindow.CheckModifiedCode(false) ||
                m_editorWindow.Modified)
                return false;

            if (m_machine.Status != MachineStatus.MACHINE_STATUS_PAUSED ||
                !m_machine.CompileComplete)
            {
                if (!PrepareForExecution())
                    return false;
            }
            SyncBreakPoints();
            return true;
        }
        //逐语句按钮动作
        private void mnuStepIn_Click(object sender, RoutedEventArgs e)
        {
            if (!PrepareForDebug()) return;
            m_machine.StepIn();
            m_stateChanged = true;
        }
        //跳出过程按钮动作
        private void mnuStepOut_Click(object sender, RoutedEventArgs e)
        {
            if (!PrepareForDebug()) return;
            m_machine.StepOut();
            m_stateChanged = true;
        }
        //逐过程按钮动作
        private void mnuStepOver_Click(object sender, RoutedEventArgs e)
        {
            if (!PrepareForDebug()) return;
            m_machine.StepOver();
            m_stateChanged = true;
        }
        //清除所有断点按钮动作
        private void ui_mnuClearBreakpoints_Click(object sender, RoutedEventArgs e)
        {
            m_editorWindow.RemoveBreakpoints();
        }

        #endregion

        #region View Commands

        /// <summary>
        /// 显示（隐藏）画布实现逻辑
        /// </summary>
        private void mnuViewCanvas_Click(object sender, RoutedEventArgs e)
        {
            if (ui_mnuViewCanvas.IsChecked)
            {
                m_canvasWindow.Close();
            }
            else
            {
                m_canvasWindow.Show();
            }
        }
        
        /// <summary>
        /// 显示（隐藏）调试工具实现逻辑
        /// </summary>
        private void mnuViewDebuggerTools_Click(object sender, RoutedEventArgs e)
        {
            if (ui_mnuViewDebuggerTools.IsChecked)
            {
                m_debuggerToolsWindow.Close();
            }
            else
            {
                m_debuggerToolsWindow.Show();
            }
        }


        #endregion

        #region Events

        /// <summary>
        /// 窗口关闭时的动作
        /// </summary>
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            //保存当前的配置信息
            SaveAutoConfig();         
            if (m_editorWindow.Modified)
            {
                if (!m_editorWindow.CheckModifiedCode(true))
                {
                    e.Cancel = true;
                    return;
                }
            }
            //停止计时器
            m_timer.Stop();
            if (m_machine != null &&
                m_machine.Status == MachineStatus.MACHINE_STATUS_RUNNING)
            {
                m_machine.Pause();
            }
            m_editorWindow.Window_Closed();
        }

        #endregion

        #region Auto Config

        
        //初始化配置文件
        private Config m_auto = new Config();
        static private readonly string autoConfigPath = AppDomain.CurrentDomain.BaseDirectory + "auto_config.cfg";

        //设置保存的配置文件中的标示字符
        private static readonly string cfg_MainWindow_Top = "MainWindow_Top";
        private static readonly string cfg_MainWindow_Left = "MainWindow_Left";
        private static readonly string cfg_MainWindow_Width = "MainWindow_Width";
        private static readonly string cfg_MainWindow_Height = "MainWindow_Height";

        private static readonly string cfg_Editor_FilePath = "Editor_FilePath";
        private static readonly string cfg_Editor_FileName = "Editor_FileName";

        private static readonly string cfg_Canvas_Top = "Canvas_Top";
        private static readonly string cfg_Canvas_Left = "Canvas_Left";
        private static readonly string cfg_Canvas_Width = "Canvas_Width";
        private static readonly string cfg_Canvas_Height = "Canvas_Height";
        private static readonly string cfg_Canvas_Show = "Canvas_Show";

        private static readonly string cfg_DebuggerTools_Top = "DebuggerTools_Top";
        private static readonly string cfg_DebuggerTools_Left = "DebuggerTools_Left";
        private static readonly string cfg_DebuggerTools_Width = "DebuggerTools_Width";
        private static readonly string cfg_DebuggerTools_Height = "DebuggerTools_Height";
        private static readonly string cfg_DebuggerTools_Show = "DebuggerTools_Show";

        /// <summary>
        /// 保存当前配置
        /// </summary>
        private void SaveAutoConfig()
        {
            m_auto.SetField(cfg_MainWindow_Top, Top.ToString());
            m_auto.SetField(cfg_MainWindow_Left, Left.ToString());
            m_auto.SetField(cfg_MainWindow_Width, Width.ToString());
            m_auto.SetField(cfg_MainWindow_Height, Height.ToString());

            m_auto.SetField(cfg_Editor_FilePath, m_editorWindow.FilePath);
            m_auto.SetField(cfg_Editor_FileName, m_editorWindow.FileName);

            m_auto.SetField(cfg_Canvas_Top, m_canvasWindow.Top.ToString());
            m_auto.SetField(cfg_Canvas_Left, m_canvasWindow.Left.ToString());
            m_auto.SetField(cfg_Canvas_Width, m_canvasWindow.Width.ToString());
            m_auto.SetField(cfg_Canvas_Height, m_canvasWindow.Height.ToString());
            m_auto.SetField(cfg_Canvas_Show, m_canvasWindow.IsVisible.ToString().ToLower());

            m_auto.SetField(cfg_DebuggerTools_Top, m_debuggerToolsWindow.Top.ToString());
            m_auto.SetField(cfg_DebuggerTools_Left, m_debuggerToolsWindow.Left.ToString());
            m_auto.SetField(cfg_DebuggerTools_Width, m_debuggerToolsWindow.Width.ToString());
            m_auto.SetField(cfg_DebuggerTools_Height, m_debuggerToolsWindow.Height.ToString());
            m_auto.SetField(cfg_DebuggerTools_Show, m_debuggerToolsWindow.IsVisible.ToString().ToLower());

            //对配置文件进行保存
            try
            {
                using (StreamWriter sw = new StreamWriter(autoConfigPath))
                    m_auto.Save(sw);
            }
            catch { }
        }

        /// <summary>
        /// 载入配置文件
        /// </summary>
        private void LoadAutoConfig()
        {
            Top = m_auto.TryGetDouble(cfg_MainWindow_Top, Top);
            Left = m_auto.TryGetDouble(cfg_MainWindow_Left, Left);
            Width = m_auto.TryGetDouble(cfg_MainWindow_Width, Width);
            Height = m_auto.TryGetDouble(cfg_MainWindow_Height, Height);

            m_editorWindow.InitialPath = m_auto.GetField(cfg_Editor_FilePath);
            m_editorWindow.InitialName = m_auto.GetField(cfg_Editor_FileName);

            m_canvasWindow.Owner = this;
            m_canvasWindow.Top = m_auto.TryGetDouble(cfg_Canvas_Top, m_canvasWindow.Top);
            m_canvasWindow.Left = m_auto.TryGetDouble(cfg_Canvas_Left, m_canvasWindow.Left);
            m_canvasWindow.Width = m_auto.TryGetDouble(cfg_Canvas_Width, m_canvasWindow.Width);
            m_canvasWindow.Height = m_auto.TryGetDouble(cfg_Canvas_Height, m_canvasWindow.Height);
            m_turtle = m_canvasWindow.Turtle;

            m_debuggerToolsWindow.Owner = this;
            m_debuggerToolsWindow.Top = m_auto.TryGetDouble(cfg_DebuggerTools_Top, m_debuggerToolsWindow.Top);
            m_debuggerToolsWindow.Left = m_auto.TryGetDouble(cfg_DebuggerTools_Left, m_debuggerToolsWindow.Left);
            m_debuggerToolsWindow.Width = m_auto.TryGetDouble(cfg_DebuggerTools_Width, m_debuggerToolsWindow.Width);
            m_debuggerToolsWindow.Height = m_auto.TryGetDouble(cfg_DebuggerTools_Height, m_debuggerToolsWindow.Height);

            m_optionWindow.Owner = this;

            if (m_auto.GetField(cfg_Canvas_Show).ToLower() != "false")
                m_canvasWindow.Show();
            if (m_auto.GetField(cfg_DebuggerTools_Show).ToLower() != "false")
                m_debuggerToolsWindow.Show();
        }

        #endregion

        /// <summary>
        /// About菜单项的动作
        /// </summary>
        private void mnuAbout_Click(object sender, RoutedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("LogoScript IDE");
            sb.AppendLine("Version: pre-alpha test");
            sb.AppendLine("Authors:");
            sb.AppendLine("\tCheng Gu,");
            sb.AppendLine("\tYuetao Hsu,");
            sb.AppendLine("\tFan Jiang,");
            sb.AppendLine("\tYuxiang Chen &");
            sb.AppendLine("\tShaoyi Wang");
            sb.AppendLine("@ 2012/6/10 SJTU School of software");
            sb.AppendLine();
            sb.AppendLine("Enjoy yourself & have fun!");
            MessageBox.Show(this, sb.ToString(), "About");
        }

        /// <summary>
        /// 退出菜单项的动作
        /// </summary>
        private void mnuExit_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// 画布窗口的单击动作，告知编辑窗口插入相关指令
        /// </summary>
        public void CanvasClick(Point pos, bool isShift)
        {
            string format;
            if (isShift)
                format = "PU(); SETXY({0}, {1}); PD();";
            else
                format = "SETXY({0}, {1});";
            m_editorWindow.InsertText(String.Format(format, (int)pos.X, (int)pos.Y));
        }
    }
}
